home *** CD-ROM | disk | FTP | other *** search
- #include <signal.h>
- #include <stdio.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- #ifndef NOSTDLIB_H
- #include <stdlib.h>
- #endif
- #ifndef NOUNISTD_H
- #include <unistd.h>
- #endif
-
- #include "fudgit.h"
- #include "setshow.h"
- #include "macro.h"
- #include "head.h"
-
- #define READ 0
- #define WRITE 1
- #ifdef NOSETPGID
- #define setpgid setpgrp
- #endif
-
- static int Plotfd = ERRR;
- static FILE *Plotfp = (FILE *)NULL;
- static int Pid = 0;
- static SIGHANDLER bangplot(int);
- static void reapit(void);
-
- extern int Ft_Interact;
- extern int Ft_Dolevel;
- extern int Ft_almost (char *, char *);
- extern int Ft_iolevel (void);
- #ifdef NeXT
- extern int putenv (const char *);
- extern char *strstr (const char *, const char *);
- #endif
-
- int plot(int init) /* return silently if init = 1 */
- {
- char *cp;
- int i;
-
- if (init && Pid) {
- return(0);
- }
- if (Ft_Plotting[0][0] == '\0') {
- if (Ft_Interact && !Ft_iolevel()) {
- fprintf(stderr, "Error: pmode: Null plotting program.\n");
- return(ERRR);
- }
- Pid = ERRR;
- }
- else if (!Pid) { /* No program running: start one */
- int pfd[2];
- struct stat buf;
-
- if (stat(Ft_Plotting[0], &buf) != 0) {
- fprintf(stderr, "Error: %s: Invalid plotting program.\n",
- Ft_Plotting[0]);
- return(ERRR);
- }
-
- if (pipe(pfd) == ERRR) {
- perror("pipe");
- return (ERRR);
- }
- Pid = fork();
- if (Pid == 0) { /* the child */
- char *vec[MAXPARG];
-
- close(0); /* close stdin */
- close(pfd[WRITE]);
- dup2(pfd[READ], 0); /* dup pipe read to plotting program stdin */
- if (pfd[READ] > 2) {
- close(pfd[READ]);
- }
- for (i=0; Ft_Plotting[i][0] != '\0' && i<MAXPARG;i++) {
- vec[i] = Ft_Plotting[i];
- }
- vec[i] = 0;
- #ifdef ultrix
- if (setpgid(0, getpid()) == ERRR) {
- #else
- if (setpgid(0, 0) == ERRR) {
- #endif
- fprintf(stderr,
- "Error: pmode: Could not set child process group to %d.\n",
- getpid());
- perror("setpgid");
- exit(1);
- }
- putenv("PAGER="); /* turn off gnuplot PAGER */
- if (execv(vec[0], vec) == ERRR) {
- sleep(1);
- fprintf(stderr,
- "Error: pmode: %s: Program not found.\n", vec[0]);
- perror("exec");
- exit(1);
- }
- }
- else if (Pid > 0) { /* the parent */
- close(pfd[READ]);
- if (Plotfd != ERRR) { /* close leftover */
- fclose(Plotfp);
- close(Plotfd);
- Plotfd = ERRR;
- }
- Plotfd = pfd[WRITE];
- if ((Plotfp = fdopen(Plotfd, "w")) == (FILE *)NULL) {
- fprintf(stderr,
- "Error: pmode: Could not get fdopen working.\n");
- close(pfd[WRITE]);
- return(ERRR);
- }
- }
- else if (Pid == ERRR) {
- perror("fork");
- close(pfd[READ]);
- close(pfd[WRITE]);
- Pid = 0;
- return(ERRR);
- }
- if (init) { /* we've done the job of init now */
- return(0);
- }
- }
- if (Ft_Interact && !Ft_iolevel())
- fprintf(stderr, "\tUse `fmode' or ^D to come back...\n");
-
- signal(SIGINT, bangplot);
- Ft_Mode = PMODE;
- while (Pid) {
- if ((cp = Ft_expandedline(Ft_Prompt_pm, EXPANSION, &i)) == (char *)0) {
- if (i) { /* end of file or ^D */
- signal(SIGINT, Ft_catcher);
- if (i > 0) /* in a file or macro */
- fprintf(stderr,
- "Warning: Eof or Eom occurred while still in pmode.\n");
- return(0);
- }
- if (Pid > 0) {
- if (write(Plotfd, "\n", 1) == ERRR) {
- reapit();
- }
- }
- continue;
- }
- if (Ft_almost(cp, "fm!ode")) {
- signal(SIGINT, Ft_catcher);
- return(0);
- }
- if (Ft_almost(cp, "pm!ode")) {
- fprintf(stderr,
- "Warning: pmode: Program already in plotting mode: Line ignored.\n");
- continue;
- }
- if (Pid > 0) {
- if (write(Plotfd, cp, strlen(cp)) == ERRR) {
- reapit();
- }
- }
- else { /* Pid == ERRR means plotting program a null string */
- fprintf(stderr, "Warning: pmode: Line ignored: %s", cp);
- }
- }
- signal(SIGINT, Ft_catcher);
- plot(1);
- if (Ft_Interact && !Ft_iolevel() && !Ft_Dolevel) {
- fprintf(stderr,
- "Warning: pmode: Dead plotting program ... restarted.\n");
- return(0);
- }
- fprintf(stderr,
- "Error: pmode: Dead plotting program ... restarted.\n");
- return(ERRR);
- }
-
-
- int Ft_dumplot(double **dblv, int ndata)
- {
- int i, j;
- extern int Plotfd;
- extern FILE *Plotfp;
-
- /* check if still alive */
- if (Pid > 0 && write(Plotfd, " ", 1) == ERRR) {
- reapit();
- fprintf(stderr,
- "Warning: pmode: Dead plotting program ... restarted.\n");
- plot(1);
- }
- else if (!Pid) {
- plot(1);
- }
-
- if (Pid > 0) {
- for (i=1;i<=ndata;i++) {
- fprintf(Plotfp, "%.9g", dblv[0][i]);
- for (j=1;dblv[j];j++) {
- fprintf(Plotfp, "\t%.9g", dblv[j][i]);
- }
- fputc('\n', Plotfp);
- }
- fflush(Plotfp);
- }
- return(0);
- }
-
- int Ft_killplot(void)
- {
- if (Pid > 0) {
- kill(Pid, SIGKILL);
- reapit();
- }
- return(0);
- }
-
- /* PMODE FUNCTION */
- #include "command.h"
-
- int Ft_pmode(int argc, char **argv, char *line, Command *cmp)
- {
- /* check if still alive */
- if (Pid > 0 && write(Plotfd, "\n", 1) == ERRR) {
- reapit();
- plot(1);
- if (!Ft_Interact || Ft_iolevel() || Ft_Dolevel) {
- fprintf(stderr,
- "Error: pmode: Dead plotting program ... restarted.\n");
- return(ERRR);
- }
- fprintf(stderr,
- "Warning: pmode: Dead plotting program ... restarted.\n");
- }
- else if (!Pid) {
- plot(1);
- }
-
- if (argc == 1) {
- return(plot(0));
- }
- else {
- char *cp;
-
- cp = strstr(line, argv[1]);
- if (Pid > 0) {
- if (write(Plotfd, cp, strlen(cp)) == ERRR) {
- reapit();
- plot(1);
- fprintf(stderr,
- "Error: pmode: Dead plotting program ... restarted.\n");
- return(ERRR);
- }
- }
- else {
- fprintf(stderr, "Warning: pmode: Line ignored: %s", cp);
- }
- return(0);
- }
- }
-
- static SIGHANDLER bangplot(int sig)
- {
- if (Pid <= 0) {
- fprintf(stderr,
- "Warning: pmode: No plotting program to interrupt!\n");
- }
- else {
- if (kill(Pid, SIGINT) != ERRR) {
- reapit();
- plot(1);
- fprintf(stderr,
- "Warning: pmode: Plotting program killed and ... restarted.\n");
- }
- else {
- fprintf(stderr,
- "Warning: pmode: Could not interrupt plotting program.\n");
- }
- }
- #ifdef RESTART_SIGHANDLER
- signal(SIGINT, bangplot);
- #endif
- #ifndef VOID_SIGHANDLER
- return(0);
- #endif
- }
-
- #include <sys/types.h>
- #include <sys/wait.h>
-
- static void reapit()
- {
- /* Use wait3 if waitpid() is not accessible */
- #ifdef NOWAITPID
- union wait status;
-
- #ifdef WAIT4
- while (wait4(Pid, &status, WNOHANG, 0) > 0) {
- #else
- while (wait3(&status, WNOHANG, 0) > 0) {
- #endif /* WAIT4 */
- #else /* NOWAITPID */
- int stat;
-
- while (waitpid((pid_t) Pid, &stat, WNOHANG) > 0) {
- #endif
- ;
- }
- Pid = 0;
- }
-
-
-